﻿

#include "Core/DefenceTower.h"

#include "Components/SphereComponent.h"
#include "Core/EnemyZDCharacter.h"
#include "PaperZDAnimInstance.h"
#include "GameFramework/DefaultPawn.h"
#include "Kismet/GameplayStatics.h"


ADefenceTower::ADefenceTower()
{
	PrimaryActorTick.bCanEverTick = true;
	
	SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("AttackRangeComponent"));
	SphereComponent->SetupAttachment(RootComponent);
	SphereComponent->SetSphereRadius(AttackRadius / 2);
}

void ADefenceTower::BeginPlay()
{
	Super::BeginPlay();

	SphereComponent->OnComponentBeginOverlap.AddDynamic(this, &ADefenceTower::OnComponentBeginOverlap);
	SphereComponent->OnComponentEndOverlap.AddDynamic(this, &ADefenceTower::OnComponentEndOverlap);

	OnAttackOverrideEndDelegate.BindUObject(this, &ADefenceTower::OnAttackOverrideEnd);
}


void ADefenceTower::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (AEnemyZDCharacter* Enemy = Cast<AEnemyZDCharacter>(OtherActor))
	{
		EnemiesList.AddUnique(Enemy);
		FindEnemyInRadius();
	}
}

void ADefenceTower::OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	if (AEnemyZDCharacter* Enemy = Cast<AEnemyZDCharacter>(OtherActor))
	{
		EnemiesList.Remove(Enemy);
		if (Enemy == AttackTarget)
		{
			AttackTarget = nullptr;
			FindEnemyInRadius();
		}
	}
}


void ADefenceTower::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	AttackTimer += DeltaTime;
	if (AttackTimer >= AttackInterval)
	{
		Attack();
	}
}

void ADefenceTower::Attack()
{
	if (AttackTarget)
	{
		AttackTimer -= AttackInterval;
		AttackTarget->OnTakeDamage(10, this);
		IsAttack = true;
		GetAnimInstance()->PlayAnimationOverride(AttackSequence, FName("DefaultSlot"), 1, 0, OnAttackOverrideEndDelegate);
	}
}


void ADefenceTower::FindEnemyInRadius()
{
	// TArray<AActor*> FoundActors;
	// UGameplayStatics::GetAllActorsOfClass(GetWorld(), AEnemyZDCharacter::StaticClass(), FoundActors);

	float MinLength = AttackRadius;
	
	FVector TowerLocation = GetActorLocation();
	for (auto Enemy : EnemiesList)
	{
		FVector EnemyLocation = Enemy->GetActorLocation();
		if (float Length = (TowerLocation - EnemyLocation).Length(); Length <= MinLength)
		{
			MinLength = Length;
			AttackTarget = Enemy;
		}
	}

	if (AttackTarget)
	{
		AttackTarget->OnSelectWasAttack();
	}
}

bool ADefenceTower::InRange(AEnemyZDCharacter* Target)
{
	const float Distance = (GetActorLocation() - Target->GetActorLocation()).Length();
	return Distance <= AttackRadius;
}

void ADefenceTower::OnAttackOverrideEnd(bool bCompleted)
{
	IsAttack = false;
}

